﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.Serialization;

namespace EOS.Framework.Web.Mvc.Controls
{
    [Serializable]
    [SuppressMessage("Microsoft.Naming", "CA1710")]
    public abstract class FormValueDictionaryBase : Dictionary<string, string>
    {
        const string MvcComponent = "Mvc.Component";

        /// <summary>
        /// Initializes a new instance of the <see cref="FormValueDictionaryBase"/> class.
        /// </summary>
        protected FormValueDictionaryBase()
            : base()
        { 
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FormValueDictionaryBase"/> class
        /// from a collection to make a copy from.
        /// </summary>
        /// <param name="collection">The collection.</param>
        protected FormValueDictionaryBase(NameValueCollection collection)
        {
            foreach (string key in collection.AllKeys)
            {
                Add(key, collection[key]);
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FormValueDictionaryBase"/> class.
        /// </summary>
        /// <param name="info">A <see cref="T:System.Runtime.Serialization.SerializationInfo"/> object containing the 
        /// information required to serialize the <see cref="T:System.Collections.Generic.Dictionary`2"/>.</param>
        /// <param name="context">A <see cref="T:System.Runtime.Serialization.StreamingContext"/> structure containing 
        /// the source and destination of the serialized stream associated with the <see cref="T:System.Collections.Generic.Dictionary`2"/>.</param>
        protected FormValueDictionaryBase(SerializationInfo info, StreamingContext context)
            : base(info, context)
        { 
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public TType GetConverted<TType>(string key)
        {
            return (TType)Injection.ChangeType(typeof(TType), this[key]);
        }

        public void Assign(object target)
        {
            foreach (string key in Keys)
            {
                if (key != MvcComponent)
                {
                    string propertyName = char.ToUpper(key[0], CultureInfo.InvariantCulture) + key.Substring(1);

                    PropertyInfo property = target.GetType().GetProperty(propertyName);
                    if (property != null)
                    {
                        try
                        {
                            property.SetValue(target, Injection.ChangeType(property.PropertyType, this[key]), null);
                        }
                        catch (FormatException)
                        {
                        }
                    }
                }
            }
        }
    }
}
